package com.zzh.lib.log;


import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;

import com.zzh.lib.core.model.LogInfo;
import com.zzh.lib.core.utils.HDateUtils;
import com.zzh.lib.core.utils.LogUtils;

import java.util.Date;

/**
 * Created by zzh on 2024/3/5.
 *
 * @date: 2024/3/5 17:08
 * @email: zzh_hz@126.com
 * @author: zzh
 * @description: com.zzh.lib.log
 */
public class Logger {
    private static final int ELEMENTS_INDEX = 1;
    boolean exceptionLogEnabled = false;
    String className;
    String methodName;
    int lineNumber;
    String filePath;
    final static int MSG_WRITE_LOG = 1;
    final static int MSG_FLUSH_LOG = 0;
    final static int MSG_RELEASE = 2;

    public boolean isExceptionLogEnabled() {
        return exceptionLogEnabled;
    }

    public Logger setExceptionLogEnabled(boolean exceptionLogEnabled) {
        this.exceptionLogEnabled = exceptionLogEnabled;
        return this;
    }

    /**
     * 写入日志路径，
     *
     * @param filePath HFileUtils.getExternalFileDir("log").getAbsolutePath() + File.separator + HDateUtils.format(new Date(), "yyyyMMdd")
     */
    public Logger setFilePath(String filePath) {
        if (!TextUtils.equals(filePath, this.filePath)) {
            if (isExceptionLogEnabled()) {
                LogUtils.d("-----zzh-log: 切换写入的旧文件路径：" + this.filePath);
                LogUtils.d("-----zzh-log: 切换写入的新文件路径：" + filePath);
            }
            this.filePath = filePath;
            getInstance().initLogRunnable();
            Handler logHandler = runnable.getLogHandler();
            if (logHandler != null) {
                logHandler.sendEmptyMessage(MSG_FLUSH_LOG);
            }
        }
        return this;
    }

    /**
     * 写入日志路径，
     *
     * @param filePath HFileUtils.getExternalFileDir("log").getAbsolutePath() + File.separator + HDateUtils.format(new Date(), "yyyyMMdd")
     * @param message  日志
     */
    public void setPathAndLog(String filePath, String message) {
        setFilePath(filePath);
        log(message);
    }

    private Logger() {
    }

    private static volatile Logger sInstance;

    public static Logger getInstance() {
        if (sInstance == null) {
            synchronized (Logger.class) {
                if (sInstance == null) {
                    sInstance = new Logger();
                    sInstance.initLogRunnable();
                }
                return sInstance;
            }
        }
        return sInstance;
    }


    private void getMethodNames(StackTraceElement[] sElements) {
        className = sElements[ELEMENTS_INDEX].getFileName();
        methodName = sElements[ELEMENTS_INDEX].getMethodName();
        lineNumber = sElements[ELEMENTS_INDEX].getLineNumber();
    }

    WriteLogRunnable runnable;
    private Thread writerThreadInstance;

    private synchronized void initLogRunnable() {
        if (runnable == null) {
            runnable = new WriteLogRunnable(this);
        }
        if (writerThreadInstance == null) {
            writerThreadInstance = new Thread(runnable, "zzh-log-writer-start");
        }
        if (writerThreadInstance.getState() == Thread.State.NEW) {
            writerThreadInstance.start();
        }
    }

    public void release() {
        if (runnable != null) {
            Handler logHandler = runnable.getLogHandler();
            logHandler.sendEmptyMessage(MSG_RELEASE);
        }
        runnable = null;
        if (writerThreadInstance != null) {
            try {
                writerThreadInstance.join(150);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            writerThreadInstance = null;
        }
        sInstance = null;

    }


    public static void log(String message) {
        if (TextUtils.isEmpty(message)) {
            if (getInstance().isExceptionLogEnabled()) {
                LogUtils.e("-----zzh-log: message 为null");
            }
        } else {
            log(new Throwable(message));
        }
    }

    public static void log(Throwable tx) {
        if (tx == null) {
            if (getInstance().isExceptionLogEnabled()) {
                LogUtils.e("-----zzh-log: tx 为null");
            }
            return;
        }
        getInstance().initLogRunnable();
        Handler logHandler = getInstance().runnable.getLogHandler();
        logHandler.removeMessages(MSG_FLUSH_LOG);
        getInstance().getMethodNames(tx.getStackTrace());

        LogInfo info = new LogInfo(getInstance().className, getInstance().methodName,
                getInstance().lineNumber, tx.getMessage() + "\n",
                HDateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss.SSS"), getInstance().filePath);

        Message msg = logHandler.obtainMessage(Logger.MSG_WRITE_LOG);
        msg.obj = info;
        logHandler.sendMessage(msg);

        if (delayNumber >= 8) {
            logHandler.sendEmptyMessage(MSG_FLUSH_LOG);
            delayNumber = 0;
        } else {
            logHandler.sendEmptyMessageDelayed(MSG_FLUSH_LOG, 200);
            delayNumber++;
        }
    }


    private static int delayNumber = 0;
}
